#pragma once

#include "GkRenderTarget.h"
#include "GkStreamDescription.h"
#include "GkRenderBinding.h"
#include "GkBuffer.h"
#include "GkGpuProgram.h"
#include "GkStateBlock.h"
#include "GkContext.h"
#include "GkConstantBuffer.h"

namespace gk
{
	class Device
	{
	public:

		virtual void 					Initialise(InitParamsHandle hInitParams) = 0;
		virtual void 					Shutdown() = 0;
		virtual bool 					Present() = 0;

		// Accessors
		virtual ContextHandle			GetSystemContext() = 0;
		virtual RenderSurfaceHandle		GetBackBuffer() = 0;
		virtual InitParamsHandle		GetInitParams() = 0;

		// Object creation
		virtual void					CreateContext(ContextHandle hContext) = 0;
		virtual void					CreateBuffer(BufferHandle hBuffer) = 0;
		virtual void					CreateRenderTarget(RenderTargetHandle hRenderTarget) = 0;
		virtual void					CreateRenderSurface(RenderSurfaceHandle hRenderSurface) = 0;
		virtual void					CreateTexture(TextureHandle hTexture) = 0;
		virtual void					CreateStreamDescription(StreamDescriptionHandle hStreamDescription) = 0;
		virtual void					CreateRenderBinding(RenderBindingHandle hRenderBinding) = 0;
		virtual void					CreateGpuProgram(GpuProgramHandle hGpuProgram) = 0;
		virtual void					CreateStateBlock(StateBlockHandle hStateBlock) = 0;
		virtual void					CreateConstantBuffer(ConstantBufferHandle hConstantBuffer) = 0;

		// Object destruction
		virtual void					ReleaseContext(ContextHandle hContext) = 0;
		virtual void					ReleaseBuffer(BufferHandle hBuffer) = 0;
		virtual void					ReleaseRenderTarget(RenderTargetHandle hRenderTarget) = 0;
		virtual void					ReleaseRenderSurface(RenderSurfaceHandle hRenderSurface) = 0;
		virtual void					ReleaseTexture(TextureHandle hTexture) = 0;
		virtual void					ReleaseStreamDescription(StreamDescriptionHandle hStreamDescription) = 0;
		virtual void					ReleaseRenderBinding(RenderBindingHandle hRenderBinding) = 0;
		virtual void					ReleaseGpuProgram(GpuProgramHandle hGpuProgram) = 0;
		virtual void					ReleaseStateBlock(StateBlockHandle hStateBlock) = 0;
		virtual void					ReleaseConstantBuffer(ConstantBufferHandle hConstantBuffer) = 0;
	};

	typedef cr::Handle<Device> DeviceHandle;
}